<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/20 0020
 * Time: 22:58
 */

namespace Lib\Core;

use Lib\Event\Event;
use Lib\Log\LogHelper;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Http\Server;

class HttpServer
{
    /**
     * @var: Http_server服务端
     */
    protected $server;
    public $redis;

    /**
     * @description:启动服务
     * @auth:yfl
     * @email:554665488@qq.com
     */
    public function run()
    {
        $config = ConfigLoad::getInstance();
        $config->load();//载入配置文件

        $httpSet = $config->get('http');
        $this->server = new Server($httpSet['host'], $httpSet['port']);
        $this->server->set($httpSet['http_setting']);
        $this->server->on('request', [$this, 'request']);
        $this->server->on('Start', [$this, 'start']);
        $this->server->on('workerStart', [$this, 'workerStart']);

        //tcp服务端口监听
        if ($httpSet['enable_tcp']) {
            $tcp = $config->get('tcp');
            $this->registerTcp($tcp);
        }

        $this->server->start();
    }

    /**
     * @description:开启Tcp的服务
     * @auth:yfl
     * @email:554665488@qq.com
     * @param $tcp
     */
    public function registerTcp($tcp)
    {
        $rpc = new RpcServer();
        $rpc->listen($this->server, $tcp);
    }

    /**
     * @description:服务调度分发
     * @auth:yfl
     * @email:554665488@qq.com
     * @param Request $request
     * @param Response $response
     */
    public function request(Request $request, Response $response)
    {
        try {
            //加载默认路由
            Router::getInstance()->dispatch($request, $response);

        } catch (\Exception $exception) {

            var_dump($exception->getMessage());
        }
    }

    /**
     * @description:服务启动后加载定时器如果文件被修改重新启动服务
     * @auth:yfl
     * @email:554665488@qq.com
     * @param \Swoole\Server $server
     */
    public function start(\Swoole\Server $server)
    {
        $ReloadWatch = ReloadWatch::getInstance();
        $ReloadWatch->watch = [CONFIG_PATH, FRAME_PATH, APP_PATH];
        $ReloadWatch->md5Flag = $ReloadWatch->getMd5();
        swoole_timer_tick(3000, function () use ($ReloadWatch) {
            if ($ReloadWatch->reload()) {
                $this->server->reload(); //重启
            }
        });
    }

    /**
     * @description:服务启动
     * @auth:yfl
     * @email:554665488@qq.com
     * @param $server
     * @param $worker_id
     */
    public function workerStart($server, $worker_id)
    {
        //支持热加载
        $config = ConfigLoad::getInstance();
        $config->loadLazy();
        //连接redis
        $this->redis = new \Redis();
        $this->redis->pconnect('127.0.0.1', 6379);
        $this->redis->auth('redis123456');
//        echo 'worker进程启动触发事件';
        //worker进程启动触发事件
        if ($worker_id == 0) Event::trigger('ws.start', [$server, $worker_id]);

        //加载路由配置文件
        include_once APP_PATH . '/route.php';
    }

    /**
     * @description:扫描事件文件注册
     * @auth:yfl
     * @email:554665488@qq.com
     * @throws \ReflectionException
     */
    public function registerEvent()
    {
        $files = glob(LISTER_PATH . '/*.php');
        if (!empty($files)) {
            foreach ($files as $index => $fileName) {
                include $fileName;
                $className = 'App\\Listener\\' . explode('.', pathinfo($fileName, PATHINFO_BASENAME))[0];

                if (class_exists($className)) {
                    $obj = new $className;
                    $reflection = new \ReflectionClass($obj);;
                    $comment = $reflection->getDocComment();
                    if (strlen($comment) < 2) {
                        throw new \Exception(' no no no ');
                    } else {
                        if (preg_match('/@Listener\((.*)\)/i', $comment, $eventName)) {
                            //LogHelper::Write($eventName[1] . '注册');
                            Event::register($eventName[1], [$obj, 'handel']);
                        } else {
                            throw  new \Exception('register event fail');
                        }

                    }

                }
            }
        }
    }
}